package com.tianbo.elfii.client.common;

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.image.*;
import javax.imageio.*;

import com.tianbo.elfii.client.common.ElfiiCommonUtil.FeedBackType;

/**  <pre>
     <b>类功能描述：</b><pre>
     完成 登录键盘 功能要求。
     </pre>
     @version 1.0.1
     @author 高伟 
*/

public class ElfiiCommonKeyboard  {

    public static int VK_LEFT_SHIFT  = 101      ;
    public static int VK_RIGHT_SHIFT = 102      ;
    public static int VK_MAP_1  = 201      ;
    public static int VK_MAP_2  = 202      ;

    JTextField textField;
    int maxTextSize=10; //-最大长度按byte计算,默认10
    JPanel keyPanel;

    String keyBgImageName;
    int keyBgImageX0;
    int keyBgImageY0;
    int keyBgWidth=785;
    int keyBgHeight=331;
    BufferedImage keyBgImage;
    
    public boolean isDigiOnly = false;

    protected int[]  keyIdA                ;
    protected String[] keyLabelA           ;
    protected String[] keyShiftLabelA      ;
    protected int[] keyX0A                 ;
    protected int[] keyY0A                 ;
    protected String[] keyNormalImgNameA       ;
    protected String[] keyNormalPressedImgNameA;
    protected String[] keyShiftPressedImgNameA ;

    protected BufferedImage[] keyNormalImgA       ;
    protected BufferedImage[] keyNormalPressedImgA;
    protected BufferedImage[] keyShiftPressedImgA ;

    protected String keyLeftShiftPressedImageName          ;
    protected String keyRightShiftPressedImageName         ;
    protected String keyLeftShiftNormalImageName          ;
    protected String keyRightShiftNormalImageName         ;
    protected BufferedImage keyLeftShiftNormalImage;
    protected BufferedImage keyRightShiftNormalImage;
    protected BufferedImage keyLeftShiftPressedImage;
    protected BufferedImage keyRightShiftPressedImage;

    protected int[] keyWidthA;
    protected int[] keyHeightA;

    protected String focusTextName=""; //-初始值必须不能是null

    boolean isLeftShiftPressed;
    int leftShiftX0=-1;
    int leftShiftY0=-1;

    boolean isRightShiftPressed;
    int rightShiftX0=-1;
    int rightShiftY0=-1;

    KeyMonitorThread keyMonitorThread;
    int infoFreshNumber ;
    int maxInfoFreshNumber=3 ; //-每一个数字代表0.1秒

    int currentKeyIndex=-1;  //-初始值必须是-1,如果不设置默认是0，页面启动时第一个键将做为按下一次处理

    int infoAreaW=500;
    int infoAreaH=50;
    JPanel infoPanel;

    String promptStr="";
    String checkedValue=null;
    java.util.Timer timer;

    boolean isTextValueChanged=false;

    public void setCheckInfo(String promptStr,String checkedValue){
        this.checkedValue=checkedValue;
        this.promptStr=promptStr;
    }
    
    public void setCheckInfo(String promptStr,int stayTime){
        this.promptStr=promptStr;
        timer = new java.util.Timer();
        timer.schedule(new ClearInfoTask(),stayTime);
    }
    
    class ClearInfoTask extends java.util.TimerTask{

		@Override
		public void run() {
			// TODO Auto-generated method stub
			promptStr="";
			timer.cancel();
		}
    	
    }

    public void checkValueUpdate(String focusTextName,String textValue,int caretPosition){
//        System.out.println("ElfiiCommonKeyboard.checkValueUpdate(String,String,int) 方法应该被重载。");
    }
    public void checkLeftCursorKey(String focusTextName,String textValue,int caretPosition){
//        System.out.println("ElfiiCommonKeyboard.checkLeftCursorKey(String,String,int) 方法应该被重载。");
    }
    public void checkRightCursorKey(String focusTextName,String textValue,int caretPosition){
//        System.out.println("ElfiiCommonKeyboard.checkRightCursorKey(String,String,int) 方法应该被重载。");
    }

    public JPanel getInfoPanel(){
        return infoPanel;
    }
 
    public void setFocusTextName(String focusTextName){
        this.focusTextName=focusTextName;
    } 
 
    public void setKeyBgImageXY(int keyBgImageX0,int keyBgImageY0){
        this.keyBgImageX0=keyBgImageX0;
        this.keyBgImageY0=keyBgImageY0;
    }
 
    public void setKeyBgImageName(String keyBgImageName){
        this.keyBgImageName=keyBgImageName;
    }
 
    public void setNormalKeyWidthHeight(int w,int h){
        if (keyWidthA==null) {
            keyWidthA=new int[keyLabelA.length];
            keyHeightA=new int[keyLabelA.length];
        }

        for (int i=0; i<keyLabelA.length; i++){
            if (keyWidthA[i]==0 && keyHeightA[i]==0){ //-防止先设置了特殊键的宽高 
                keyWidthA[i]=w;
                keyHeightA[i]=h;
            }
        }
    }

    public void setSpecialKeyWidthHeight(int keyId,int w,int h){
        for (int i=0; i<keyLabelA.length; i++){
            if (keyIdA[i]==keyId){
                keyWidthA[i]=w;
                keyHeightA[i]=h;
            }
        }
    }

    public void setTextField(JTextField textField,int maxTextSize){
        this.textField=textField;
        this.maxTextSize=maxTextSize;
        if(this.textField!=null)
        textField.selectAll();
//        textField.select(0, 1);
    } 

    public JTextField getTextField(){
        return textField;
    }

    public JPanel createKeyPanel(){

        keyNormalImgA=new BufferedImage[keyNormalImgNameA.length];
        keyNormalPressedImgA=new BufferedImage[keyNormalPressedImgNameA.length];
        keyShiftPressedImgA=new BufferedImage[keyShiftPressedImgNameA.length];

        for (int i=0; i<keyNormalImgA.length; i++){
            if (keyIdA[i]==VK_LEFT_SHIFT){
                leftShiftX0=keyX0A[i];
                leftShiftY0=keyY0A[i];
                keyLeftShiftPressedImageName=keyNormalPressedImgNameA[i];
                keyLeftShiftNormalImageName=keyNormalImgNameA[i];
            }
            if (keyIdA[i]==VK_RIGHT_SHIFT){
                rightShiftX0=keyX0A[i];
                rightShiftY0=keyY0A[i];
                keyRightShiftNormalImageName=keyNormalImgNameA[i];
                keyRightShiftPressedImageName=keyNormalPressedImgNameA[i];
            }
        }

        File f=null;

        try {

            if (keyBgImageName!=null){
                f=new File(keyBgImageName);
                keyBgImage=ImageIO.read(f);
            }

            f=new File(keyLeftShiftNormalImageName);
            keyLeftShiftNormalImage=ImageIO.read(f);
            f=new File(keyRightShiftNormalImageName);
            keyRightShiftNormalImage=ImageIO.read(f);
            f=new File(keyLeftShiftPressedImageName);
            keyLeftShiftPressedImage=ImageIO.read(f);
            f=new File(keyRightShiftPressedImageName);
            keyRightShiftPressedImage=ImageIO.read(f);

            for (int i=0; i<keyNormalImgA.length; i++){
                f=new File(keyNormalImgNameA[i]);
                keyNormalImgA[i]=ImageIO.read(f);
                f=new File(keyNormalPressedImgNameA[i]);
                keyNormalPressedImgA[i]=ImageIO.read(f);
            }
            for (int i=0; i<keyShiftPressedImgA.length; i++){
                if (keyShiftPressedImgNameA[i]!=null) {
                    f=new File(keyShiftPressedImgNameA[i]);
                    keyShiftPressedImgA[i]=ImageIO.read(f);
                }
            }
        } catch(Exception e) {System.out.println(e+" "+f);}

        keyPanel = new JPanel() {
                public void paintComponent(Graphics g) {
                    super.paintComponent(g);

                    Graphics2D g2 = (Graphics2D) g ;
                    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

//                    g2.setColor(Color.black);
//                    g2.fillRect(0,0,keyBgWidth,keyBgHeight);

                    if (keyBgImage!=null){
                        g2.drawImage(keyBgImage,null,keyBgImageX0,keyBgImageY0);
                    }

                    g2.setColor(Color.white);
                    g2.fillRoundRect(keyBgImageX0,keyBgImageY0,keyBgWidth,keyBgHeight,40,40);

                    for (int i=0; i<keyNormalImgA.length; i++){
                        g2.drawImage(keyNormalImgA[i],null,keyX0A[i],keyY0A[i]);
                    }
                    if (currentKeyIndex>=0 && infoFreshNumber<maxInfoFreshNumber) {
                        if ((isLeftShiftPressed==true || isRightShiftPressed==true )){
                            if (keyShiftPressedImgA[currentKeyIndex]!=null)
                                g2.drawImage(keyShiftPressedImgA[currentKeyIndex],null,keyX0A[currentKeyIndex],keyY0A[currentKeyIndex]);
                            else
                                g2.drawImage(keyNormalPressedImgA[currentKeyIndex],null,keyX0A[currentKeyIndex],keyY0A[currentKeyIndex]);
                        }else{
                            g2.drawImage(keyNormalPressedImgA[currentKeyIndex],null,keyX0A[currentKeyIndex],keyY0A[currentKeyIndex]);
                        }
                        infoFreshNumber++;
                    }

                    if (isLeftShiftPressed==true || isRightShiftPressed==true){
                        g2.drawImage(keyLeftShiftPressedImage,null,leftShiftX0,leftShiftY0);
                        g2.drawImage(keyRightShiftPressedImage,null,rightShiftX0,rightShiftY0);
                    }else{
                        g2.drawImage(keyLeftShiftNormalImage,null,leftShiftX0,leftShiftY0);
                        g2.drawImage(keyRightShiftNormalImage,null,rightShiftX0,rightShiftY0);
                    }
                    
                    //testXY(g2);
                }
                public Dimension getPreferredSize() {
                    //=====return (new Dimension(keyBgWidth,keyBgHeight));
                    return (new Dimension(400,200));
                }
                public void testXY(Graphics2D g2){
                    g2.setColor(Color.green);
                    g2.setFont(new Font(ElfiiCommonConstant.Font_Name,Font.BOLD,20));
                    for (int i=0; i<keyLabelA.length; i++){
                        g2.drawRect(keyX0A[i],keyY0A[i],keyWidthA[i],keyHeightA[i]);
                        g2.drawString(keyLabelA[i],keyX0A[i]+3,keyY0A[i]+20);
                    }
                }
            };
        keyPanel.addMouseListener(new MouseAdapter(){

            public void mouseReleased(MouseEvent e) {
                maxInfoFreshNumber=0;
                keyPanel.repaint();
            }

            public void mousePressed(MouseEvent e) {
            	if(textField==null)
            		return;
                isTextValueChanged=false;
                maxInfoFreshNumber=3000;
                infoFreshNumber=0;
                currentKeyIndex=-1;
                int x=e.getX();
                int y=e.getY();
                int p=textField.getCaretPosition();
                String text=textField.getText();
                int preCaretPosition=p;
                String preTextValue=text;
                //System.out.println("鼠标XY: "+e.getX()+","+e.getY());  //-坐标值是相对于面板的边界的，面板右移时，该值并不变。
                //System.out.println("文本光标位置:"+p);
                String str=null;
                String keyChar="";
                int keyId=-999;
                for (int i=0; i<keyX0A.length; i++){
                    //System.out.println("======x1:"+keyX0A[i]+" x2:"+(keyX0A[i]+keyWidthA[i]) +" y1:"+keyY0A[i]+" y2:"+(keyY0A[i]+keyHeightA[i]));
                    if (x>keyX0A[i] && x<keyX0A[i]+keyWidthA[i] && y>keyY0A[i] && y<keyY0A[i]+keyHeightA[i]) {
                        currentKeyIndex=i;
                        keyId=keyIdA[i];
                        if (keyLabelA[i].length()==1) {
                            if (isLeftShiftPressed==false && isRightShiftPressed==false)
                                keyChar=keyLabelA[i];
                            else
                                keyChar=keyShiftLabelA[i];
                        }
                    }
                }

                if (keyChar.length()==1){ //-普通字符
                	
                	if(isDigiOnly){

                		char[] ch = keyChar.toCharArray();
                	
                		if(!Character.isDigit(ch[0]))
                			return;
                	}
                	
                    promptStr="";
                    str=text;

                    int s1=textField.getSelectionStart();
                    int s2=textField.getSelectionEnd();
                    //System.out.println("======S12p: "+s1+", "+s2+",  "+p);
                    if (s1==s2) //-没有选择
                        str=str.substring(0,p)+keyChar+str.substring(p,str.length());
                    else
                        str=str.substring(0,s1)+keyChar+str.substring(s2,str.length());

                    if (str.getBytes().length>maxTextSize){
                        while (str.getBytes().length>maxTextSize){
                            str=str.substring(0,str.length()-1);
                        }
                    }
                    textField.setText(str);
                    textField.requestFocus();

                    try {
                        if (s1==s2) //-没有选择
                            textField.setCaretPosition(p+1);
                        else
                            textField.setCaretPosition(s1+1);
                    }catch(Exception e2){}

                    int k=textField.getCaretPosition();
                    if (k>=maxTextSize)
                        checkRightCursorKey(focusTextName,textField.getText(),k);
                    isTextValueChanged=true;
                }

                if (keyId==KeyEvent.VK_BACK_SPACE){
                    //-如果没有选中区域，s1=s2
                    int s1=textField.getSelectionStart();
                    int s2=textField.getSelectionEnd();
                    //System.out.println("======S12p: "+s1+", "+s2+",  "+p);

                    if (p>0 && s1==s2){
                        str=text;
                        str=str.substring(0,p-1)+str.substring(p,str.length());
                        textField.setText(str);
                        textField.requestFocus();
                        textField.setCaretPosition(p-1);
                    }
                    if (p>0 && s2>s1 && s2==p){
                        str=text;
                        str=str.substring(0,s1)+str.substring(s2,str.length());
                        textField.setText(str);
                        textField.requestFocus();
                        textField.setCaretPosition(s1);
                    }

                    if (p==0)
                        checkLeftCursorKey(focusTextName,textField.getText(),0);
                    isTextValueChanged=true;
                }

                if (keyId==VK_LEFT_SHIFT){
                    if (isLeftShiftPressed==true || isRightShiftPressed==true){
                        isLeftShiftPressed=false;
                        isRightShiftPressed=false;
                    }else{
                        isLeftShiftPressed=true;
                        isRightShiftPressed=true;
                    }
                }
                if (keyId==VK_RIGHT_SHIFT){
                    if (isLeftShiftPressed==true || isRightShiftPressed==true){
                        isLeftShiftPressed=false;
                        isRightShiftPressed=false;
                    }else{
                        isLeftShiftPressed=true;
                        isRightShiftPressed=true;
                    }
                }
                if (keyId==KeyEvent.VK_LEFT){
                    if (p-1>=0)
                        textField.setCaretPosition(p-1);
                    checkLeftCursorKey(focusTextName,textField.getText(),p);
                }
                if (keyId==KeyEvent.VK_RIGHT){
                    if (text.length()>=p+1)
                        textField.setCaretPosition(p+1);
                    checkRightCursorKey(focusTextName,textField.getText(),p);
                }

                infoPanel.repaint();
                keyPanel.repaint();

                if (isTextValueChanged==true) {
                    checkValueUpdate(focusTextName,textField.getText(),textField.getCaretPosition());
                }
                
                ElfiiCommonUtil.playFeedbackAudio(FeedBackType.CLICK);
            }
          }
        );

        keyMonitorThread = new KeyMonitorThread();
//        keyMonitorThread.start();

        return keyPanel;
    }


    public void dispatchEvent(KeyEvent e){
        String str;
        String keyChar="";
        int p=textField.getCaretPosition();
        int keyId=e.getKeyChar();
        String text=textField.getText();
        if (keyId==KeyEvent.VK_SHIFT){
            if (isLeftShiftPressed==true)
                isLeftShiftPressed=false;
            else
                isLeftShiftPressed=true;
        }
        if (keyId==KeyEvent.VK_BACK_SPACE){
            if (p>0){
                str=text;
                str=str.substring(0,p-1)+str.substring(p,str.length());
                textField.setText(str);
                textField.requestFocus();
                textField.setCaretPosition(p-1);
            }
        }
        if (keyId==KeyEvent.VK_LEFT){
            if (p-1>=0)
                textField.setCaretPosition(p-1);
        }
        if (keyId==KeyEvent.VK_RIGHT){
            if (text.length()>=p+1)
                textField.setCaretPosition(p+1);
        }
    }
    public void dispatchEvent(MouseEvent e){
        int x=e.getX();
        int y=e.getY();
        String str;
        String keyChar="";
        int p=textField.getCaretPosition();
        int keyId=keyIdA[0];
        String text=textField.getText();
        if (keyId==KeyEvent.VK_SHIFT){
            if (isLeftShiftPressed==true)
                isLeftShiftPressed=false;
            else
                isLeftShiftPressed=true;
        }
        if (keyId==KeyEvent.VK_BACK_SPACE){
            if (p>0){
                str=text;
                str=str.substring(0,p-1)+str.substring(p,str.length());
                textField.setText(str);
                textField.requestFocus();
                textField.setCaretPosition(p-1);
            }
        }
        if (keyId==KeyEvent.VK_LEFT){
            if (p-1>=0)
                textField.setCaretPosition(p-1);
        }
        if (keyId==KeyEvent.VK_RIGHT){
            if (text.length()>=p+1)
                textField.setCaretPosition(p+1);
        }
    }

    class KeyMonitorThread extends Thread implements KeyListener,MouseListener{
        boolean  goOn ;
    
        public void keyPressed(KeyEvent e) {
            dispatchEvent(e);
        }
        public void keyReleased(KeyEvent e) {
            dispatchEvent(e);
        }
        public void keyTyped(KeyEvent e) {
            dispatchEvent(e);
        }

        public void mouseExited(java.awt.event.MouseEvent e){
            dispatchEvent(e);
        }

        public void mousePressed(MouseEvent e) {
            dispatchEvent(e);
        }

        public void mouseClicked(MouseEvent e) {
            dispatchEvent(e);
        }

        public void mouseEntered(java.awt.event.MouseEvent e){
            dispatchEvent(e);
        }

        public void mouseReleased(java.awt.event.MouseEvent e){
            dispatchEvent(e);
        }

        public void setGoOn(boolean goOn) {
            this.goOn=goOn ;
        }

        public void run() {
            goOn = true ;
            try {
                String oldPromptStr=null;
                String oldCheckedValue=null;

                while (goOn) {

                    keyPanel.repaint();
                    if (infoPanel!=null)  //必须判断一下 2012-08-04
                        infoPanel.repaint();

                    if (checkedValue!=null){
                        oldPromptStr=promptStr;
                        oldCheckedValue=checkedValue;
                        textField.setText(checkedValue); //-=====这一步执行后，promptStr和checkedValue都会改变，错误会消失，要提前保留。
                    }

                    Thread.currentThread().sleep(100);

                    if (oldCheckedValue!=null){
                        promptStr=oldPromptStr;
                        if (oldCheckedValue.length()>0)
                            promptStr+="，更正为"+oldCheckedValue;
                        oldCheckedValue=null;
                    }
                }
            } catch(Exception ee) {System.out.print("KeyBoard Monitor: "+ee);}
        }
    }

    public static String space(int spaceLength) {
        String kkstr="";
        for (int i=0; i<spaceLength; i++)
            kkstr=kkstr+" ";
        return kkstr ;
    }

    public void stopKeyboardThread(){
        if (keyMonitorThread!=null)
            keyMonitorThread.setGoOn(false);
    }

    public JPanel createInfoPanel(){
        infoPanel = new JPanel() {
                public void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    Graphics2D g2 = (Graphics2D) g ;
                    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
                    g2.setColor(Color.black);
                    g2.fillRect(0,0,infoAreaW,infoAreaH);
                    g2.setColor(ElfiiCommonConstant.Elfii_Red);
                    g2.setFont(new Font(ElfiiCommonConstant.Font_Name,Font.PLAIN,20));
                    g2.drawString(promptStr,0,20);
                }
                public Dimension getPreferredSize() {
                    return (new Dimension(400,55));
                }
            };
        infoPanel.setBackground(Color.blue);
        return infoPanel;
    }
}
